package com.candy.codegen.manager;


import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.candy.codegen.constant.GenConstants;
import com.candy.codegen.domain.entity.GenTable;
import com.candy.codegen.mapper.GenTableMapper;
import com.candy.codegen.domain.param.GenTableSaveParam;
import com.candy.codegen.util.StringUtils;
import com.candy.codegen.util.VelocityUtils;
import com.candy.codegen.domain.vo.GenTableColumnVO;
import com.candy.codegen.domain.vo.GenTableVO;
import com.mybatisflex.core.query.QueryChain;
import jakarta.annotation.PostConstruct;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.File;
import java.util.List;

import static com.candy.codegen.domain.entity.table.GenTableTableDef.GEN_TABLE;


/**
 * 代码生成表业务处理层
 * @author rong xi
 * @version 1.0
 * @date 2023/09/14 23:44
 */
@Component
@AllArgsConstructor
@Slf4j
public class GenTableManager {

    private static GenTableManager manager = null;
    private final GenTableMapper genTableMapper;

    @PostConstruct
    private void init(){
        manager = this;
    }

    /**
     * 根据表名称查询数据库表列表
     * @param tableNames 表名称
     * @return 代码生成表列表
     */
    @SuppressWarnings("all")
    public static List<GenTable> listDBTableByTableNames(@NonNull List<String> tableNames){
        return QueryChain.of(manager.genTableMapper)
        .select(GEN_TABLE.TABLE_NAME,GEN_TABLE.TABLE_COMMENT,GEN_TABLE.CREATE_TIME,GEN_TABLE.UPDATE_TIME,GEN_TABLE.TABLE_SCHEMA)
        .from(" information_schema.TABLES` as `gen_table")
        .where("table_schema = (SELECT DATABASE())")
        .and(GEN_TABLE.TABLE_NAME.notLikeLeft("QRTZ_"))
        .and(GEN_TABLE.TABLE_NAME.notLikeLeft("gen_"))
        .and(("table_name not in (SELECT table_name FROM gen_table)"))
        .and(GEN_TABLE.TABLE_NAME.in(tableNames))
        .list();
    }

    /**
     * 检查更新对象
     * @param param 更新对象参数
     */
    public static void validateEdit(GenTableSaveParam param) {
        if (GenConstants.TPL_TREE.equals(param.getTplCategory())) {
            if(CollectionUtil.isEmpty(param.getParams())){
                throw new RuntimeException("树相关参数不能为空");
            }
            String options = JSON.toJSONString(param.getParams());
            JSONObject paramsObj = JSONObject.parseObject(options);
            if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_CODE))) {
                throw new RuntimeException("树编码字段不能为空");
            } else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_PARENT_CODE))) {
                throw new RuntimeException("树父编码字段不能为空");
            } else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_NAME))) {
                throw new RuntimeException("树名称字段不能为空");
            }
        } else if (GenConstants.TPL_SUB.equals(param.getTplCategory())) {
            if (StringUtils.isEmpty(param.getSubTableName())) {
                throw new RuntimeException("关联子表的表名不能为空");
            } else if (StringUtils.isEmpty(param.getSubTableFkName())) {
                throw new RuntimeException("子表关联的外键名不能为空");
            }
        }
    }

    /**
     * 设置主键列信息
     * @param table 表VO
     */
    public static void setPkColumn(GenTableVO table) {
        for (GenTableColumnVO column : table.getColumns()) {
            if (GenConstants.YES.equals(column.getIsPk())){
                table.setPkColumn(column);
                break;
            }
        }
        if (StringUtils.isNull(table.getPkColumn())) {
            table.setPkColumn(table.getColumns().get(0));
        }
        if (GenConstants.TPL_SUB.equals(table.getTplCategory())) {
            for (GenTableColumnVO column : table.getSubTable().getColumns()) {
                if (GenConstants.YES.equals(column.getIsPk())){
                    table.getSubTable().setPkColumn(column);
                    break;
                }
            }
            if (StringUtils.isNull(table.getSubTable().getPkColumn())) {
                table.getSubTable().setPkColumn(table.getSubTable().getColumns().get(0));
            }
        }
    }

    /**
     * 设置代码生成其他选项值
     * @param vo 设置后的生成对象
     */
    public static void setTableFromOptions(GenTableVO vo) {
        JSONObject paramsObj = JSONObject.parseObject(vo.getOptions());
        if (paramsObj != null) {
            String treeCode = paramsObj.getString(GenConstants.TREE_CODE);
            String treeParentCode = paramsObj.getString(GenConstants.TREE_PARENT_CODE);
            String treeName = paramsObj.getString(GenConstants.TREE_NAME);
            String parentMenuId = paramsObj.getString(GenConstants.PARENT_MENU_ID);
            String parentMenuName = paramsObj.getString(GenConstants.PARENT_MENU_NAME);

            vo.setTreeCode(treeCode);
            vo.setTreeParentCode(treeParentCode);
            vo.setTreeName(treeName);
            vo.setParentMenuId(parentMenuId);
            vo.setParentMenuName(parentMenuName);
        }
    }

    /**
     * 获取代码生成地址
     * @param table    业务表信息
     * @param template 模板文件路径
     * @return 生成地址
     */
    public static String getGenPath(GenTableVO table, String template) {
        String genPath = table.getGenPath();
        if (StringUtils.equals(genPath, "/")) {
            return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table);
        }
        return genPath + File.separator + VelocityUtils.getFileName(template, table);
    }


}
